package arm_search_3.data;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Term adalah kelas representasi term yang diekstrak dari dokumen
 *
 * @author Muqtafi Akhmad
 */
public class Term implements Serializable {

    /**
     * panjang maksimal sebuah term
     */
    public static Integer max_term_length = 50;
    /**
     * string dari term
     */
    private String termString;
    /**
     * statistik dari term
     */
    private Statistic statistic;

    /**
     * konstruktor term, dengan masukan term string
     *
     * @param termString string term
     */
    public Term(String termString) {
        this.termString = termString;
    }

    /**
     * mengembalikan path index file dari term dengan parameter term directory
     * dari worker
     *
     * @param termDir term directory dari worker
     * @return path ke file index dari term
     */
    public String getPath(String termDir) {
        File tempSubfolder = new File(termDir + File.separator + this.getTermString().charAt(0));
        if (tempSubfolder.exists()) {
            return termDir + File.separator + this.getTermString().charAt(0) + File.separator + this.getTermString();
        } else {
            return termDir + File.separator + "etc" + File.separator + this.getTermString();
        }
    }

    /**
     * load term dari file ke dalam memory
     *
     * @param filePath path ke index file dari term
     */
    public void loadTerm(String filePath) {
        try {
            
            InputStream file = new FileInputStream(filePath);
            InputStream buffer = new BufferedInputStream(file);
            ObjectInput input = new ObjectInputStream(buffer);
            
            Term tempTerm = (Term) input.readObject();
            this.termString = tempTerm.termString;
            this.statistic = tempTerm.statistic;
            input.close();
            buffer.close();
            file.close();
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Term.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Term.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * menyimpan term ke dalam file
     *
     * @param filePath file path ke index file dari term
     */
    public void saveTerm(String filePath) {
        try {
            OutputStream file = new FileOutputStream(filePath);
            OutputStream buffer = new BufferedOutputStream(file);
            ObjectOutput output = new ObjectOutputStream(buffer);
            try {
                output.writeObject(this);
            } finally {
                output.close();
                buffer.close();
                file.close();
            }
        } catch (IOException ex) {
        }
    }

    /**
     * menggabungkan term ke dalam file index yang telah ada, jika file belum
     * ada term akan langsung dituliskan
     *
     * @param filePath path ke file index dari term
     */
    public void mergeTerm(String filePath) {
        File checkFile = new File(filePath);
        // file sudah ada, gabungkan dengan term yang akan dituliskan
        if (checkFile.exists()) {
            Term tempTerm = new Term(this.getTermString());
            tempTerm.loadTerm(filePath);
            this.statistic.merge(tempTerm.getStatistic());
        }
        try {
            OutputStream file = new FileOutputStream(filePath);
            OutputStream buffer = new BufferedOutputStream(file);
            ObjectOutput output = new ObjectOutputStream(buffer);
            try {
                // tuliskan term ke dalam file
                output.writeObject(this);
            } finally {
                output.close();
                buffer.close();
                file.close();
            }
        } catch (IOException ex) {
        }
    }

    /**
     * mengembalikan term string
     *
     * @return representasi term string
     */
    @Override
    public String toString() {
        return this.getTermString() + this.statistic.toString();
    }

    /**
     * membandingkan satu term dan term lain dengan membandingkan representasi
     * stringnya
     *
     * @param object objek lain yang dibangingkan
     * @return apakah term sama dengan term lain
     */
    @Override
    public boolean equals(Object object) {
        Term objTerm = (Term) object;
        return this.getTermString().equals(objTerm.getTermString());
    }

    /**
     * mengembalikan term string
     *
     * @return term string
     */
    public String getTermString() {
        return this.termString;
    }

    /**
     * mengisikan term string
     *
     * @param termString term string
     */
    public void setTermString(String termString) {
        this.termString = termString;
    }

    /**
     * mengisikan objek statistic untuk mentatat statistik term
     *
     * @param statistic objek statistik
     */
    public void setStatistic(Statistic statistic) {
        this.statistic = statistic;
    }

    /**
     * mengembalikan objek statistic dari term
     *
     * @return objek statistik
     */
    public Statistic getStatistic() {
        return this.statistic;
    }
}